import { fabric } from 'fabric';
import initPointControls from './initPointToControls';
import { EventsTypes, events } from '../utils/events';

// 竖线
const verticalImg = 'https://ossprod.jrdaimao.com/file/1691055918106919.svg';
// 圆点
const edgeImg = 'https://ossprod.jrdaimao.com/file/1691055938230666.svg';
// 旋转
const rotateImg = 'https://ossprod.jrdaimao.com/file/1717490595794332.svg';
// 横线
const horizontalImg = 'https://ossprod.jrdaimao.com/file/1691055964267980.svg';
// 剪裁
const clipImg = 'https://ossprod.jrdaimao.com/file/1719385030936751.svg';
// 删除
const deleteImg = 'https://ossprod.jrdaimao.com/file/1719915856498782.svg';

/**
 * 实际场景: 在进行某个对象缩放的时候，由于fabricjs默认精度使用的是toFixed(2)。
 * 此处为了缩放的精度更准确一些，因此将NUM_FRACTION_DIGITS默认值改为4，即toFixed(4).
 */
fabric.Object.NUM_FRACTION_DIGITS = 4;
// 全局取消旋转功能
fabric.Object.prototype.hasRotatingPoint = false;

export function drawImg(ctx: CanvasRenderingContext2D, left: number, top: number, img: HTMLImageElement, wSize: number, hSize: number, angle: number | undefined) {
    if (angle === undefined) return;
    ctx.save();
    ctx.translate(left, top);
    ctx.rotate(fabric.util.degreesToRadians(angle));
    ctx.drawImage(img, -wSize / 2, -hSize / 2, wSize, hSize);
    ctx.restore();
}

// 中间横杠
function intervalControl() {
    const verticalImgIcon = document.createElement('img');
    verticalImgIcon.src = verticalImg;

    const horizontalImgIcon = document.createElement('img');
    horizontalImgIcon.src = horizontalImg;

    function renderIcon(ctx: CanvasRenderingContext2D, left: number, top: number, styleOverride: string, fabricObject: fabric.Object) {
        drawImg(ctx, left, top, verticalImgIcon, 20, 25, fabricObject.angle);
    }

    function renderIconHoz(ctx: CanvasRenderingContext2D, left: number, top: number, styleOverride: string, fabricObject: fabric.Object) {
        drawImg(ctx, left, top, horizontalImgIcon, 25, 20, fabricObject.angle);
    }
    // 中间横杠
    fabric.Object.prototype.controls.ml = new fabric.Control({
        x: -0.5,
        y: 0,
        offsetX: -1,
        cursorStyleHandler: fabric.controlsUtils.scaleSkewCursorStyleHandler,
        actionHandler: fabric.controlsUtils.scalingXOrSkewingY,
        getActionName: fabric.controlsUtils.scaleOrSkewActionName,
        render: renderIcon,
    });

    fabric.Object.prototype.controls.mr = new fabric.Control({
        x: 0.5,
        y: 0,
        offsetX: 1,
        cursorStyleHandler: fabric.controlsUtils.scaleSkewCursorStyleHandler,
        actionHandler: fabric.controlsUtils.scalingXOrSkewingY,
        getActionName: fabric.controlsUtils.scaleOrSkewActionName,
        render: renderIcon,
    });

    fabric.Object.prototype.controls.mb = new fabric.Control({
        x: 0,
        y: 0.5,
        offsetY: 1,
        cursorStyleHandler: fabric.controlsUtils.scaleSkewCursorStyleHandler,
        actionHandler: fabric.controlsUtils.scalingYOrSkewingX,
        getActionName: fabric.controlsUtils.scaleOrSkewActionName,
        render: renderIconHoz,
    });

    fabric.Object.prototype.controls.mt = new fabric.Control({
        x: 0,
        y: -0.5,
        offsetY: -1,
        cursorStyleHandler: fabric.controlsUtils.scaleSkewCursorStyleHandler,
        actionHandler: fabric.controlsUtils.scalingYOrSkewingX,
        getActionName: fabric.controlsUtils.scaleOrSkewActionName,
        render: renderIconHoz,
    });
}

// 顶点
function peakControl() {
    const img = document.createElement('img');
    img.src = edgeImg;

    function renderIconEdge(ctx: CanvasRenderingContext2D, left: number, top: number, styleOverride: string, fabricObject: fabric.Object) {
        drawImg(ctx, left, top, img, 25, 25, fabricObject.angle);
    }
    // 四角图标
    fabric.Object.prototype.controls.tl = new fabric.Control({
        x: -0.5,
        y: -0.5,
        cursorStyleHandler: fabric.controlsUtils.scaleCursorStyleHandler,
        actionHandler: fabric.controlsUtils.scalingEqually,
        render: renderIconEdge,
    });
    fabric.Object.prototype.controls.bl = new fabric.Control({
        x: -0.5,
        y: 0.5,
        cursorStyleHandler: fabric.controlsUtils.scaleCursorStyleHandler,
        actionHandler: fabric.controlsUtils.scalingEqually,
        render: renderIconEdge,
    });
    fabric.Object.prototype.controls.tr = new fabric.Control({
        x: 0.5,
        y: -0.5,
        cursorStyleHandler: fabric.controlsUtils.scaleCursorStyleHandler,
        actionHandler: fabric.controlsUtils.scalingEqually,
        render: renderIconEdge,
    });
    fabric.Object.prototype.controls.br = new fabric.Control({
        x: 0.5,
        y: 0.5,
        cursorStyleHandler: fabric.controlsUtils.scaleCursorStyleHandler,
        actionHandler: fabric.controlsUtils.scalingEqually,
        render: renderIconEdge,
    });
}

// 旋转
function rotationControl() {
    const img = document.createElement('img');
    img.src = rotateImg;
    const clipImageEl = document.createElement('img');
    clipImageEl.src = clipImg;
    const deleteImageEl = document.createElement('img');
    deleteImageEl.src = deleteImg;

    function changePoints(eventData: string, transform: { target: fabric.Group & { canvas: fabric.Canvas } }) {
        const target = transform.target;
        if (!target) return;
        const poly = target.getObjects().find((item: fabric.Object) => item.type === 'polygon');
        if (!poly) return;
        target.visible = false;
        target.canvas.discardActiveObject();
        target.canvas.renderAll();
        poly.clone((e: fabric.Polygon) => {
            e.set({
                left: target.left,
                top: target.top,
                objectCaching: false,
                transparentCorners: false,
                formId: target.id,
                id: 'changePointsPoly',
            });
            initPointControls(e);
            target.canvas.add(e);
            target.canvas.setActiveObject(e);
            target.canvas.renderAll();
        });
    }
    // 删除
    function deleteObject(eventData: string, transform: { target: fabric.Group & { canvas: fabric.Canvas } }) {
        const target = transform.target;
        const canvas = transform.target.canvas;
        if (target) {
            events.emit(EventsTypes.DeleteObject, [target]);
            canvas.remove(target);
            canvas.renderAll();
        }
    }
    fabric.Object.prototype.controls.mtr = new fabric.Control({
        x: 0,
        y: 0.5,
        cursorStyleHandler: fabric.controlsUtils.rotationStyleHandler,
        actionHandler: fabric.controlsUtils.rotationWithSnapping,
        offsetY: 30,
        offsetX: 0,
        actionName: 'rotate',
        render: () => '',
    });
    // // 旋转图标
    // fabric.Object.prototype.controls.rotate1 = new fabric.Control({
    //     x: 0,
    //     y: 0.5,
    //     cursorStyleHandler: fabric.controlsUtils.rotationStyleHandler,
    //     actionHandler: fabric.controlsUtils.rotationWithSnapping,
    //     offsetY: 30,
    //     offsetX: -15,
    //     actionName: 'rotate',
    //     render: (ctx, left, top, styleOverride, fabricObject) => {
    //         if (!fabricObject.isEditPoint) {
    //             drawImg(ctx, left, top, img, 40, 40, fabricObject.angle);
    //         }
    //     },
    // });
    // // 旋转图标2
    // fabric.Object.prototype.controls.rotate2 = new fabric.Control({
    //     x: 0,
    //     y: 0.5,
    //     cursorStyleHandler: fabric.controlsUtils.rotationStyleHandler,
    //     actionHandler: fabric.controlsUtils.rotationWithSnapping,
    //     offsetY: 30,
    //     offsetX: -30,
    //     actionName: 'rotate',
    //     render: (ctx, left, top, styleOverride, fabricObject) => {
    //         if (fabricObject.isEditPoint) {
    //             drawImg(ctx, left, top, img, 40, 40, fabricObject.angle);
    //         }
    //     },
    // });
    // 修改点位
    fabric.Object.prototype.controls.cp = new fabric.Control({
        x: 0,
        y: 0.5,
        cursorStyleHandler: fabric.controlsUtils.rotationStyleHandler,
        mouseUpHandler: changePoints,
        cursorStyle: 'pointer',
        offsetY: 30,
        offsetX: 0,
        actionName: 'cp',
        render: (ctx, left, top, styleOverride, fabricObject) => {
            if (fabricObject.isEditPoint) {
                drawImg(ctx, left, top, clipImageEl, 24, 24, fabricObject.angle);
            }
        },
    });
    // 删除
    fabric.Object.prototype.controls.delete = new fabric.Control({
        x: 0,
        y: 0.5,
        cursorStyleHandler: fabric.controlsUtils.rotationStyleHandler,
        mouseUpHandler: deleteObject,
        cursorStyle: 'pointer',
        offsetY: 30,
        offsetX: 15,
        actionName: 'cp',
        render: (ctx, left, top, styleOverride, fabricObject) => {
            if (!fabricObject.isEditPoint) {
                drawImg(ctx, left, top, deleteImageEl, 24, 24, fabricObject.angle);
            }
        },
    });
    // 删除2
    fabric.Object.prototype.controls.delete2 = new fabric.Control({
        x: 0,
        y: 0.5,
        cursorStyleHandler: fabric.controlsUtils.rotationStyleHandler,
        mouseUpHandler: deleteObject,
        cursorStyle: 'pointer',
        offsetY: 30,
        offsetX: 30,
        actionName: 'cp',
        render: (ctx, left, top, styleOverride, fabricObject) => {
            if (fabricObject.isEditPoint) {
                drawImg(ctx, left, top, deleteImageEl, 24, 24, fabricObject.angle);
            }
        },
    });
}

class ControlsPlugin {
    public canvas: fabric.Canvas;
    static pluginName = 'ControlsPlugin';
    constructor(canvas: fabric.Canvas) {
        this.canvas = canvas;
        this.init();
    }
    init() {
        // 删除图标
        // deleteControl(this.canvas);
        // 顶点图标
        peakControl();
        // 中间横杠图标
        intervalControl();
        // 旋转图标
        rotationControl();

        // 选中样式
        fabric.Object.prototype.set({
            transparentCorners: false,
            borderColor: 'rgba(118,19,254,1)',
            cornerColor: '#FFF',
            borderScaleFactor: 2.5,
            cornerStyle: 'circle',
            cornerStrokeColor: '#0E98FC',
            borderOpacityWhenMoving: 1,
        });
        // textbox保持一致
        // fabric.Textbox.prototype.controls = fabric.Object.prototype.controls;
    }

    destroy() {
        console.log('pluginDestroy');
    }
}

export default ControlsPlugin;
